<template>
  <div
    v-if="!initializing"
    class="vc-component"
    :style="visual.parseStyle(currNode.currStyle)"
  >
    <div ref="chartDiv" class="vc-echarts-annular" :style="style"></div>
  </div>
  <div
    v-else
    v-loading="true"
    element-loading-text=""
    style="min-height: 30px;"
    class="vc-component"
    :style="visual.parseStyle(currNode.currStyle)"
  ></div>
</template>

<script setup>
import { ref, onMounted, computed, inject, getCurrentInstance, markRaw, nextTick, onUnmounted } from 'vue';
import * as echarts from "echarts";
import visual from "@/visual/js/visual";
import EventHandler from "@/visual/js/event";
import JSON5 from 'json5';
import tool from "@/utils/tool";

const props = defineProps({
  node: Object,
  inputParam: Object
});

const chartDiv = ref();
const currChart = ref(null);
const initializing = ref(true);
const currNode = ref(props.node);
const eventHandler = new EventHandler(
  inject('eventHandler', Function, true),
  getCurrentInstance(),
  currNode.value
);

const init = async(styleId) => {
  initializing.value = true;
  visual.initStyle(currNode.value, styleId);
  await nextTick(() => initializing.value = false);
};

const loadData = tool.debounce(async() => {
  if (!chartDiv.value) return;
  const compStyle = currNode.value.currCompStyle || {};
  const defaultOption = JSON5.parse(compStyle['jsonOption'] || '{}');
  const dataList = (await visual.loadData(
    currNode.value.compData,
    eventHandler,
    getData(),
    currNode.value)).data || []
  const data = dataList.length > 0 ? dataList[0] : {};
  const gaugeData = [{
    value: data['百分比'] || 0,
    name: `{a|${data['显示值']}}`
      + (data['标题'] ? `{b|${('\n' + data['标题'])}}` : '')
  }];

  const option = {
    color: [compStyle['progressColor'] || '#5470c6'],
    series: [
      {
        type: 'gauge',
        startAngle: 90,
        endAngle: -270,
        pointer: {
          show: false
        },
        progress: {
          show: true,
          overlap: false,
          roundCap: true,
          clip: false,
        },
        axisLine: {
          lineStyle: {
            width: compStyle['borderWidth'] || 8,
            color: [
              [1, compStyle['borderColor'] || 'rgba(0, 0, 0, 0.1)'],
            ]
          }
        },
        splitLine: {
          show: false,
          distance: 0,
          length: 10
        },
        axisTick: {
          show: false
        },
        axisLabel: {
          show: false,
          distance: 10
        },
        data: gaugeData,
        title: {
          show: true,
          offsetCenter: ['0%', '5%'],
          rich: {
            a: {
              color: compStyle['series.value.color'] || 'inherit',
              fontSize: compStyle['series.value.fontSize'] || 14,
              fontFamily: compStyle['series.value.fontFamily'],
              fontWeight: compStyle['series.value.fontWeight'],
              lineHeight: compStyle['series.value.fontSize'] || 14
            },
            b: {
              color: compStyle['series.title.color'] || 'inherit',
              fontSize: compStyle['series.title.fontSize'] || 14,
              fontFamily: compStyle['series.title.fontFamily'],
              fontWeight: compStyle['series.title.fontWeight'],
              lineHeight: compStyle['series.value.fontSize'] || 14
            }
          }
        },
        detail: {
          show: false,
        }
      }
    ]
  };

  await nextTick(() => initializing.value = false);
  await nextTick(() => {
    if (!chartDiv.value) return;
    if (currChart.value) currChart.value.dispose();
    currChart.value = markRaw(echarts.init(chartDiv.value));
    currChart.value.setOption(Object.assign({}, option, defaultOption));
  });
  resize();
});

const style = computed(() => {
  const compStyle = currNode.value.currCompStyle || {};

  let result = '';
  result += visual.parseTpl('width: {value};', compStyle['width']);
  result += visual.parseTpl('height: {value};', compStyle['height']);
  return result;
});

const getData = () => {
  return {
    inputParam: props.inputParam || {}
  };
};

const changeStyle = (styleId) => {
  init(styleId);
};

const refresh = async() => {
  await init();
  loadData();
};

const resize = () => {
  try {
    currChart.value.resize();
  } catch (e) {
    console.log(e);
  }
};

onMounted(async() => {
  await init();
  loadData();
});

onUnmounted(() => {
  eventHandler.unregister();
});

defineExpose({ getData, changeStyle, refresh, loadData });
</script>